package com.imdroid.carac.activities;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.mapapi.navi.BaiduMapAppNotSupportNaviException;
import com.baidu.mapapi.navi.BaiduMapNavigation;
import com.baidu.mapapi.navi.NaviPara;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKBusLineResult;
import com.baidu.mapapi.search.MKDrivingRouteResult;
import com.baidu.mapapi.search.MKPoiResult;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.search.MKSearchListener;
import com.baidu.mapapi.search.MKSuggestionResult;
import com.baidu.mapapi.search.MKTransitRouteResult;
import com.baidu.mapapi.search.MKWalkingRouteResult;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.imdroid.carac.IMDroid;
import com.imdroid.carac.R;
import com.imdroid.carac.model.Destination;

/**
 * 选择常用导航点
 * 
 */
public class NavigatorPointsPickup extends Activity {

	/**
	 * The tag of the map activity
	 */
	private static final String TAG = "NavigatorPointsPickup";
	/**
	 * The map view;
	 */
	private MapView mapView;
	/**
	 * The current city
	 */
	public String currentCity;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;
	/**
	 * The controller of the map;
	 */
	private MapController mapController;
	/**
	 * The MK Search
	 */
	private MKSearch mKSearch;
	/**
	 * The default zoon level
	 */
	private static final int defailtZoomLevel = 15;
	/**
	 * The address of this address name
	 */
	private static String addressName = null;

	/**
	 * The search full address
	 */
	private String searchFullAddress = null;
	/**
	 * The progress dialog
	 */
	private static ProgressDialog waitingDialog;

	/**
	 * The overlay of the destination
	 */
	private DestinationOverlay destinationOverlay;
	/**
	 * The gesture detector
	 */
	private GestureDetector gestureDetector;
	/**
	 * if set the center already
	 */
	private boolean setCenter = true;
	// 定位相关
	private LocationClient mLocClient;
	private MyLocationListenner myListener = new MyLocationListenner();

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		// 初始化界面
		super.onCreate(savedInstanceState);
		setContentView(R.layout.loc_navigator_pickup);
		mapView = (MapView) this.findViewById(R.id.loc_mapview);
		mapView.setBuiltInZoomControls(true);

		// 初始化地图
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;


		mapController = mapView.getController();
		mapController.setZoom(defailtZoomLevel);
		mapView.setDoubleClickZooming(true);
		mapView.setLongClickable(true);
		// GPS定位
		mLocClient = new LocationClient(this);
		mLocClient.registerLocationListener(myListener);

		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType("bd09ll"); // 设置坐标类型
		option.setScanSpan(3000);
		mLocClient.setLocOption(option);
		mLocClient.start();
		
		// 初始化地图
		if (bMapManager != null) {
			bMapManager.start();
		}

		// 初始化MKSearch类:
		mKSearch = new MKSearch();
		mKSearch.init(bMapManager, mapSearchListener);
		// 设置手势的处理
		gestureDetector = new GestureDetector(this, new MapGestureListener());

		mapView.setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				gestureDetector.onTouchEvent(event);
				return false;
			}
		});
		// 定义软键盘的“搜查”按钮的定义
		EditText editText = (EditText) this
				.findViewById(R.id.loc_address_keyword);
		editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_SEARCH) {
					InputMethodManager imm = (InputMethodManager) v
							.getContext().getSystemService(
									Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
					NavigatorPointsPickup.this
							.search(NavigatorPointsPickup.this
									.findViewById(R.id.loc_btn_search));
					return true;
				}
				return false;
			}

		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onResume()
	 */
	protected void onResume() {
		super.onResume();
		// 获取常用地址的ID
		Log.d(TAG, "AddressName: " + addressName);
		if (this.getIntent() != null && this.getIntent().getExtras() != null)
			addressName = this.getIntent().getExtras().getString("addressName");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		if (mLocClient != null) {
			mLocClient.unRegisterLocationListener(myListener);
			mLocClient.stop();
		}
		if (bMapManager != null) {
			bMapManager.stop();
		}

	}

	/**
	 * The action when clicking the back button
	 * 
	 * @param view
	 *            the button of back
	 */
	public void back(View view) {
		startActivity(new Intent(this, NavigatorPointSetting.class));
		finish();
	}

	/**
	 * Search address
	 * 
	 * @param view
	 *            the button of view
	 */
	public void search(View view) {
		EditText keyWord = (EditText) this
				.findViewById(R.id.loc_address_keyword);
		if (keyWord.getText() == null || keyWord.getText().length() <= 0) {
			Toast.makeText(this, this.getString(R.string.loc_no_address),
					Toast.LENGTH_LONG).show();
			return;
		}
		Log.d(TAG, "Search--" + keyWord.getText());
		// 打开提示框
		if (waitingDialog != null) {
			waitingDialog.dismiss();
		}
		waitingDialog = ProgressDialog.show(this,
				this.getString(R.string.loc_address_title),
				this.getString(R.string.loc_address_wait));
		// waitingDialog.setCancelable(true);

		// 查询地址
		searchFullAddress = keyWord.getText() + "";
		if (currentCity != null && searchFullAddress.indexOf(currentCity) < 0) {
			searchFullAddress = currentCity + searchFullAddress;
		}

		mKSearch.suggestionSearch(searchFullAddress, currentCity);
	}

	/**
	 * Send the destination
	 * 
	 * @param destination
	 *            the destination to be send
	 */
	private void setDestination(Destination destination) {
		// 设置屏幕中心
		if (destination != null) {
			final GeoPoint pt = new GeoPoint(
					(int) (destination.getLatitude() * 1000000),
					(int) (destination.getLongitude() * 1000000));
			mapController.setCenter(pt);
		}

		if (addressName != null && addressName.length() > 0) {
			destination.setName(addressName);
			Destination.saveDestination(destination);
		}
		back(NavigatorPointsPickup.this.findViewById(R.id.loc_back));
	}

	/**
	 * Sending the address
	 * 
	 * @param destination
	 *            the destination to be send
	 */
	private void navi(final Destination destination) {
		final BDLocation currentLocation = IMDroid.getCurrentLocation();

		if (currentLocation == null) {
			Toast.makeText(this,
					this.getString(R.string.loc_error_no_gps_wait),
					Toast.LENGTH_LONG).show();
			return;
		}

		final Activity actvity = NavigatorPointsPickup.this;
		// 弹出对话框
		AlertDialog.Builder buidler = new AlertDialog.Builder(actvity);
		buidler.setMessage(R.string.loc_confirm);
		// 按钮 - 发送
		buidler.setPositiveButton(
				NavigatorPointsPickup.this.getString(R.string.loc_okay),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {

						double mLat1 = currentLocation.getLatitude();
						double mLon1 = currentLocation.getLongitude();
						double mLat2 = destination.getLatitude();
						double mLon2 = destination.getLongitude();
						int lat = (int) (mLat1 * 1E6);
						int lon = (int) (mLon1 * 1E6);

						GeoPoint pt1 = new GeoPoint(lat, lon);
						lat = (int) (mLat2 * 1E6);
						lon = (int) (mLon2 * 1E6);
						GeoPoint pt2 = new GeoPoint(lat, lon);

						NaviPara para = new NaviPara();
						para.startPoint = pt1; // 起点坐标
						para.startName = actvity
								.getString(R.string.loc_map_loc);
						para.endPoint = pt2; // 终点坐标
						para.endName = destination.getAddress();
						try {
							BaiduMapNavigation.openBaiduMapNavi(para, actvity);
							actvity.finish();
						} catch (BaiduMapAppNotSupportNaviException e) {
							// 在此处理异常
							e.printStackTrace();
						}

					}
				});
		// 按钮 - 取消
		buidler.setNegativeButton(
				NavigatorPointsPickup.this.getString(R.string.loc_cancel),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						return;
					}
				});
		buidler.show();

	}

	/**
	 * Start the navitation without the confirmation
	 * 
	 * @param destination
	 *            the destination to be send
	 */
	private void naviWithoutConfirm(final Destination destination) {
		final BDLocation currentLocation = IMDroid.getCurrentLocation();
		final Activity actvity = NavigatorPointsPickup.this;

		if (currentLocation == null) {
			Toast.makeText(this,
					this.getString(R.string.loc_error_no_gps_wait),
					Toast.LENGTH_LONG).show();
			return;
		}

		double mLat1 = currentLocation.getLatitude();
		double mLon1 = currentLocation.getLongitude();
		double mLat2 = destination.getLatitude();
		double mLon2 = destination.getLongitude();
		int lat = (int) (mLat1 * 1E6);
		int lon = (int) (mLon1 * 1E6);

		GeoPoint pt1 = new GeoPoint(lat, lon);
		lat = (int) (mLat2 * 1E6);
		lon = (int) (mLon2 * 1E6);
		GeoPoint pt2 = new GeoPoint(lat, lon);

		NaviPara para = new NaviPara();
		para.startPoint = pt1; // 起点坐标
		para.startName = actvity.getString(R.string.loc_map_loc);
		para.endPoint = pt2; // 终点坐标
		para.endName = destination.getAddress();
		try {
			BaiduMapNavigation.openBaiduMapNavi(para, actvity);
			actvity.finish();
		} catch (BaiduMapAppNotSupportNaviException e) {
			// 在此处理异常
			e.printStackTrace();
		}

	}

	/**
	 * The seach listener of the map
	 */
	private MKSearchListener mapSearchListener = new MKSearchListener() {
		/**
		 * The name of the destination;
		 */
		private String destinationAddress;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetAddrResult(com.baidu.mapapi
		 * .MKAddrInfo, int)
		 */
		public void onGetAddrResult(final MKAddrInfo result, int error) {
			// 解除对话框
			if (waitingDialog != null)
				waitingDialog.dismiss();
			Context context = NavigatorPointsPickup.this;

			// 如果百度查找有错
			if (error != 0) {
				Toast.makeText(
						NavigatorPointsPickup.this,
						context.getString(R.string.loc_map_destination_error)
								+ "(Error Code:" + error + ")",
						Toast.LENGTH_LONG).show();
				return;
			}

			// 设置地图中心
			if (result.geoPt != null)
				mapController.setCenter(result.geoPt);

			// 如果搜索地址为空（即从长按中进入）
			if (searchFullAddress == null) {
				// 弹出对话框
				AlertDialog.Builder buidler = new AlertDialog.Builder(
						NavigatorPointsPickup.this);
				buidler.setTitle(R.string.loc_address_title);
				// 确认文字
				String text = NavigatorPointsPickup.this
						.getString(R.string.loc_nav_confirm);
				text = text.replace("%1%", result.strAddr);
				buidler.setMessage(text);
				buidler.setIcon(android.R.drawable.ic_dialog_info);

				// 按钮 - 发送
				buidler.setPositiveButton(
						NavigatorPointsPickup.this
								.getString((addressName != null && addressName
										.length() > 0) ? R.string.loc_dia_sy
										: R.string.loc_start_navi),
						new OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								Destination d = new Destination();
								d.setAddress(result.strAddr);
								d.setLatitude((float) (result.geoPt
										.getLatitudeE6() / 1e6));
								d.setLongitude((float) (result.geoPt
										.getLongitudeE6() / 1e6));
								// 如果是设置常用地址
								if (addressName != null
										&& addressName.length() > 0) {
									setDestination(d);
									back(NavigatorPointsPickup.this
											.findViewById(R.id.loc_back));
								} else {
									// 如果是设置直接导航
									naviWithoutConfirm(d);
								}

							}
						});
				// 按钮 - 取消
				buidler.setNegativeButton(NavigatorPointsPickup.this
						.getString(R.string.loc_dia_sn), new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						return;
					}
				});
				buidler.show();

			} else {
				// 设置目的地
				Destination d = new Destination();
				d.setAddress(destinationAddress);
				d.setLatitude((float) (result.geoPt.getLatitudeE6() / 1e6));
				d.setLongitude((float) (result.geoPt.getLongitudeE6() / 1e6));

				int action = (addressName != null && addressName.length() > 0) ? 1
						: 2;

				// 添加目的地图层
				if (destinationOverlay != null)
					mapView.getOverlays().remove(destinationOverlay);

				destinationOverlay = new DestinationOverlay(d, action, context
						.getResources().getDrawable(R.drawable.icon_marka),
						mapView);

				OverlayItem overlayItem = new OverlayItem(result.geoPt,
						"item1", context.getString(R.string.loc_click_navi));
				destinationOverlay.addItem(overlayItem);

				mapView.getOverlays().add(destinationOverlay);
				mapView.getController().animateTo(result.geoPt);
				mapView.refresh();

			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetBusDetailResult(com.baidu.
		 * mapapi.MKBusLineResult, int)
		 */
		public void onGetBusDetailResult(MKBusLineResult result, int error) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetDrivingRouteResult(com.baidu
		 * .mapapi.MKDrivingRouteResult, int)
		 */
		@Override
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetPoiResult(com.baidu.mapapi
		 * .MKPoiResult, int, int)
		 */
		public void onGetPoiResult(MKPoiResult res, int type, int error) {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.search.MKSearchListener#onGetSuggestionResult(com
		 * .baidu.mapapi.search.MKSuggestionResult, int)
		 */
		public void onGetSuggestionResult(MKSuggestionResult result, int iError) {
			// 解除对话框
			if (waitingDialog != null)
				waitingDialog.dismiss();
			// 如果没有找到目的地
			if (iError != 0 || result == null) {
				Toast.makeText(
						NavigatorPointsPickup.this,
						NavigatorPointsPickup.this
								.getString(R.string.loc_map_destination_error)
								+ " " + iError, Toast.LENGTH_LONG).show();
				return;
			}

			// 把目的地组成数组，准备显示选择
			int nSize = result.getSuggestionNum();
			// 如果找不到地址，则通过地址解释查找
			if (nSize <= 0) {
				Log.d(TAG, "Search by full address....");

				// 如果找不到建议，则通过地址解释查找
				BDLocation currentLocation = IMDroid.getCurrentLocation();
				Context context = NavigatorPointsPickup.this;
				if (currentLocation == null) {
					Toast.makeText(context,
							context.getString(R.string.loc_error_no_gps_wait),
							Toast.LENGTH_LONG).show();
					return;
				}
				destinationAddress = searchFullAddress;
				mKSearch.geocode(searchFullAddress, currentLocation.getCity());

				return;
			}

			final String[] mStrSuggestions = new String[nSize];
			for (int i = 0; i < nSize; i++)
				mStrSuggestions[i] = result.getSuggestion(i).city + "-"
						+ result.getSuggestion(i).key;
			destinationAddress = null;
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					NavigatorPointsPickup.this);
			String address = NavigatorPointsPickup.this
					.getString(R.string.loc_map_destination_name);
			buidler.setTitle(address);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setSingleChoiceItems(mStrSuggestions, 0,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							// 记下选择的地址
							destinationAddress = mStrSuggestions[which];
						}
					});
			// 判断是直接导航还是设置地址
			int textId = (addressName != null && addressName.length() > 0) ? R.string.loc_dia_sy
					: R.string.loc_start_navi;
			// 按钮 - 发送
			buidler.setPositiveButton(
					NavigatorPointsPickup.this.getString(textId),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];
							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);
						}
					});
			// 按钮 - 取消
			buidler.setNegativeButton(
					NavigatorPointsPickup.this.getString(R.string.loc_dia_sn),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							ProgressDialogHelper.dismissProgress();
						}
					});
			buidler.show();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.search.MKSearchListener#onGetTransitRouteResult(
		 * com.baidu.mapapi.search.MKTransitRouteResult, int)
		 */
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.search.MKSearchListener#onGetWalkingRouteResult(
		 * com.baidu.mapapi.search.MKWalkingRouteResult, int)
		 */
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.search.MKSearchListener#onGetPoiDetailSearchResult
		 * (int, int)
		 */
		public void onGetPoiDetailSearchResult(int type, int error) {

		}

	};

	/**
	 * The map gesture linstener
	 * 
	 */
	private class MapGestureListener extends SimpleOnGestureListener {
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.view.GestureDetector.SimpleOnGestureListener#onLongPress(
		 * android.view.MotionEvent)
		 */
		public void onLongPress(MotionEvent e) {
			final GeoPoint myGeoPoint = mapView.getProjection().fromPixels(
					(int) e.getX(), (int) e.getY());
			if (myGeoPoint == null)
				return;
			searchFullAddress = null;
			// 打开提示框
			if (waitingDialog != null) {
				waitingDialog.dismiss();
			}
			Context context = NavigatorPointsPickup.this;
			waitingDialog = ProgressDialog.show(context,
					context.getString(R.string.loc_address_title),
					context.getString(R.string.loc_address_wait));

			mKSearch.reverseGeocode(new GeoPoint(myGeoPoint.getLatitudeE6(),
					myGeoPoint.getLongitudeE6()));
		}
	}

	/**
	 * The destination overr lay
	 * 
	 */
	private class DestinationOverlay extends ItemizedOverlay<OverlayItem> {
		/**
		 * 目的地
		 */
		Destination destination;
		/**
		 * 1-设置常用地址，其他-导航
		 */
		int action;

		/**
		 * The constructor
		 * 
		 * @param arg0
		 *            the icon drawable
		 * @param arg1
		 *            the mapview
		 */
		public DestinationOverlay(Destination destination, int action,
				Drawable arg0, MapView arg1) {
			super(arg0, arg1);
			this.destination = destination;
			this.action = action;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.map.ItemizedOverlay#onTap(int)
		 */
		protected boolean onTap(int index) {
			Log.d(TAG, "ACTION----------" + action);
			if (action == 1) {

				final Activity actvity = NavigatorPointsPickup.this;
				// 弹出对话框
				AlertDialog.Builder buidler = new AlertDialog.Builder(actvity);
				buidler.setMessage(R.string.loc_cofirm_address);
				// 按钮 - 发送
				buidler.setPositiveButton(
						NavigatorPointsPickup.this.getString(R.string.loc_okay),
						new OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								setDestination(destination);
							}
						});
				// 按钮 - 取消
				buidler.setNegativeButton(NavigatorPointsPickup.this
						.getString(R.string.loc_cancel), new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						return;
					}
				});
				buidler.show();

			} else {
				navi(destination);
			}

			return true;
		}
	}

	/**
	 * 监听函数，又新位置的时候，格式化成字符串，输出到屏幕中
	 */
	public class MyLocationListenner implements BDLocationListener {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.location.BDLocationListener#onReceiveLocation(com.baidu
		 * .location.BDLocation)
		 */
		public void onReceiveLocation(BDLocation arg0) {
			if (arg0 != null && setCenter) {
				mapController.animateTo(new GeoPoint(
						(int) (arg0.getLatitude() * 1e6), (int) (arg0
								.getLongitude() * 1e6)));
				setCenter = false;
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.location.BDLocationListener#onReceivePoi(com.baidu.location
		 * .BDLocation)
		 */
		public void onReceivePoi(BDLocation arg0) {
		}

	}
}
